package com.manner.groupon.service.groupon.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.manner.groupon.common.BaseResponse;
import com.manner.groupon.common.PageRequest;
import com.manner.groupon.common.PageResult;
import com.manner.groupon.common.ResultUtils;
import com.manner.groupon.constant.BusinessConstant;
import com.manner.groupon.constant.DeductionCouponStatus;
import com.manner.groupon.constant.PayMethod;
import com.manner.groupon.exception.CustomException;
import com.manner.groupon.mapper.*;
import com.manner.groupon.model.dto.grouponCoupons.BuyGrouponCouponsRequest;
import com.manner.groupon.model.dto.grouponCoupons.StoreQueryGrouponCoupon;
import com.manner.groupon.model.dto.grouponOrder.CalculationDistanceArgs;
import com.manner.groupon.model.dto.pay.PayDTO;
import com.manner.groupon.model.entity.*;
import com.manner.groupon.model.enums.GrouponCouponsStatus;
import com.manner.groupon.model.enums.OrderStatus;
import com.manner.groupon.model.vo.AdminCouponVO;
import com.manner.groupon.model.vo.CouponItem;
import com.manner.groupon.model.vo.GroupCouponPackageVo;
import com.manner.groupon.model.vo.GroupCouponVo;
import com.manner.groupon.service.groupon.GroupPurchasePackageService;
import com.manner.groupon.service.groupon.GrouponCouponsService;
import com.manner.groupon.service.pay.PayService;
import com.manner.groupon.utils.GrouponOrderIdGenerate;
import com.manner.groupon.utils.RedisIdWorker;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.manner.groupon.constant.BusinessConstant.*;
import static com.manner.groupon.constant.DeductionCouponStatus.USED_ALREADY;
import static com.manner.groupon.model.enums.OrderStatus.REFUND_LOADING;
import static com.manner.groupon.model.enums.RefundApprovalRecordStatus.UNDER_APPROVAL;


/**
 * 团购优惠券业务实现类
 *
 * @author manner
 * @description 针对表[tb_groupon_coupons(团购优惠券表)]的数据库操作Service实现
 * @createDate 2024-10-11 01:43:00
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class GrouponCouponsServiceImpl extends ServiceImpl<GrouponCouponsMapper, GrouponCoupons> implements GrouponCouponsService {

    //团购券
    private final GrouponCouponsMapper grouponCouponsMapper;
    //团购订单
    private final GrouponOrderMapper grouponOrderMapper;
    //商家
    private final StoreMapper storeMapper;
    //团购编号生成策略
    private final GrouponOrderIdGenerate grouponOrderIdGenerate;
    //优惠券套餐
    private final GroupPurchasePackageService groupPurchasePackageService;
    //支付
    private final PayService payService;
    //Redis全局ID生成
    private final RedisIdWorker redisIdWorker;
    //用户
    private final UserMapper userMapper;
    //订单抵扣券
    private final DeductionCouponMapper deductionCouponMapper;

    private final StoreLinkManMapper storeLinkManMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    private final RefundApprovalRecordMapper refundApprovalRecordMapper;


    /**
     * @param orderUserId    下单用户的编号
     * @param grouponOrderId 订单编号
     * @description: 检查用户下单是否满足返利给邀请人优惠券的条件
     * @author Manner
     * @date 2024/12/1 22:51
     */
    public void checkRebateCondition(Long orderUserId, String grouponOrderId) {
        //查询下单用户数据
        User orderUser = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getId, orderUserId));
        if (orderUser == null || !StrUtil.isNotBlank(orderUser.getInvitePhone())) {
            return;
        }
        //该用户为被人邀请注册的,查询这笔订单是否为该用户首单
        GrouponOrder isCurrentUserOneOrder = grouponOrderMapper.selectOne(new LambdaQueryWrapper<GrouponOrder>()
                .ne(GrouponOrder::getId, grouponOrderId));
        //不是首单
        if (BeanUtil.isNotEmpty(isCurrentUserOneOrder)) {
            return;
        }
        //首单,获取该用户注册的时间
        LocalDateTime createTime = LocalDateTime.parse(orderUser.getCreateTime(), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
        //获取当前时间
        LocalDateTime now = LocalDateTime.now();
        //时差天数
        long daysBetween = ChronoUnit.DAYS.between(createTime, now);
        //再判断是否是在注册30天以内下单的
        if (daysBetween > 30) {
            return;
        }
        //是注册内30天内首单,查询邀请该用户注册的用户信息
        User invitePeople = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getPhone, orderUser.getInvitePhone()));
        //计算分数
        Long scoreNumber = Long.valueOf(Integer.valueOf(DEDUCTION_COUPON) * CONVERSION_MULTIPLIER);
        //构建订单抵扣券信息
        DeductionCoupon deductionCoupon = DeductionCoupon.builder()
                .userId(invitePeople.getId())
                .title("邀请新用户返利" + Integer.valueOf(DEDUCTION_COUPON) + "元")
                .amount(new BigDecimal(DEDUCTION_COUPON))
                .amountScore(scoreNumber)
                .effectiveDays(BusinessConstant.INFINITE_NUMBER)
                .status(DeductionCouponStatus.NOT_USED)
                .description("满" + Integer.valueOf(DEDUCTION_COUPON) + "元全站通用")
                .expirationDateText("无过期时间")
                .build();
        //返利给邀请人优惠券一张
        deductionCouponMapper.insert(deductionCoupon);
    }


    /**
     * @param grouponCouponsId 团购优惠券编号
     * @description: 下架团购优惠
     * @author Manner
     * @date 2024/12/5 19:06
     */
    @Override
    public void linkmanRemoveGrouponCoupon(Long grouponCouponsId, int status) {
        GrouponCoupons grouponCoupon = grouponCouponsMapper.selectOne(new LambdaQueryWrapper<GrouponCoupons>()
                .eq(GrouponCoupons::getId, grouponCouponsId));
        grouponCoupon.setStatus(status);
        grouponCouponsMapper.updateById(grouponCoupon);
    }

    /**
     * @param phone 登录手机号账号
     * @return List<StoreQueryGrouponCoupon>
     * @description: 商户门店联系人查询自己名下店铺的所有团购优惠券
     * @author Manner
     * @date 2024/12/5 17:25
     */
    @Override
    public List<StoreQueryGrouponCoupon> queryMyAllGrouponCoupons(String phone) {
        //准备返回数据的容器
        List<StoreQueryGrouponCoupon> storeQueryGrouponCoupons = new ArrayList<>();
        //查询联系人信息
        StoreLinkMan storeLinkMan = storeLinkManMapper.selectOne(new LambdaQueryWrapper<StoreLinkMan>()
                .eq(StoreLinkMan::getPhone, phone));
        //查询名下所有店铺的信息
        List<Store> stores = storeMapper.selectList(new LambdaQueryWrapper<Store>()
                .eq(Store::getAdminId, storeLinkMan.getId()));
        //收集所有店铺编号
        List<String> storeNOs = stores.stream()
                .map(Store::getStoreNo)
                .collect(Collectors.toList());
        //范围查询所有优惠券
        List<GrouponCoupons> grouponCoupons = grouponCouponsMapper.selectList(new LambdaQueryWrapper<GrouponCoupons>()
                .in(GrouponCoupons::getStoreId, storeNOs));
        //数据拷贝
        grouponCoupons.forEach(grouponCoupon -> {
            storeQueryGrouponCoupons.add(BeanUtil.copyProperties(grouponCoupon, StoreQueryGrouponCoupon.class));
        });
        //给每张团购优惠券设置店铺名称
        storeQueryGrouponCoupons.forEach(storeQueryGrouponCoupon -> {
            String name = storeMapper.selectOne(new LambdaQueryWrapper<Store>().eq(Store::getStoreNo, storeQueryGrouponCoupon.getStoreId())).getName();
            storeQueryGrouponCoupon.setStoreName(name);
            //时间格式化
            String createTime = storeQueryGrouponCoupon.getCreateTime();
            String formatDateTime = createTime.replace("T", " ");
            storeQueryGrouponCoupon.setCreateTime(formatDateTime);
        });
        return storeQueryGrouponCoupons;
    }

    /**
     * @param grouponCoupons
     * @return BaseResponse
     * @description: 平台内部员工对团购优惠券进行编辑更新
     * @author Manner
     * @date 2024/11/10 16:52
     */
    @Transactional(rollbackFor = Throwable.class)
    @Override
    public void staffEdit(GrouponCoupons grouponCoupons) {
        //编辑更新之后需要管理员重新审核
        grouponCoupons.setStatus(GrouponCouponsStatus.UNAUDITED.getCode());
        //更新数据库记录
        grouponCouponsMapper.updateById(grouponCoupons);
    }

    /**
     * @param grouponCouponsId
     * @param statusCode
     * @return BaseResponse
     * @description: 管理员审核平台内部员工上架的团购优惠券
     * @author Manner
     * @date 2024/11/10 16:32
     */
    @Transactional(rollbackFor = Throwable.class)
    @Override
    public BaseResponse toExamineUpdate(Long grouponCouponsId, Integer statusCode) {
        //查询需要审核的团购优惠券信息
        GrouponCoupons examineGrouponCoupons = grouponCouponsMapper
                .selectOne(new LambdaQueryWrapper<GrouponCoupons>()
                        .eq(GrouponCoupons::getId, grouponCouponsId)
                );
        //更新审核状态
        examineGrouponCoupons.setStatus(statusCode);
        //更新数据库记录
        grouponCouponsMapper.updateById(examineGrouponCoupons);
        return ResultUtils.success("审核操作完成!");
    }

    /**
     * 扣减库存,生成团购券订单记录
     *
     * @param grouponOrderId 生成的团购券订单编号
     * @param payAmountId    第三方支付编号
     * @param totalAmount    支付金额
     * @param request        下单优惠券的请求参数对象
     * @param grouponCoupons 优惠券信息
     * @author Manner
     * @date 2024/10/13 0:44
     */
    @Transactional(rollbackFor = Throwable.class)
    public void generateGrouponOrder(String grouponOrderId,
                                     String payAmountId,
                                     BigDecimal totalAmount,
                                     BuyGrouponCouponsRequest request,
                                     GrouponCoupons grouponCoupons) {
        //查询是否持有抵扣支付金额的优惠券
        DeductionCoupon deductionCoupon = deductionCouponMapper.selectOne(new LambdaQueryWrapper<DeductionCoupon>()
                .eq(DeductionCoupon::getUserId, request.getUserId()));
        if (BeanUtil.isEmpty(deductionCoupon)) {
            throw new CustomException("订单使用的优惠券不存在!");
        }
        totalAmount = totalAmount.subtract(deductionCoupon.getAmount());
        deductionCoupon.setStatus(USED_ALREADY);
        //使用后更新状态,更新数据库记录行
        deductionCouponMapper.updateById(deductionCoupon);

        //生成订单数据准备
        GrouponOrder grouponOrder = GrouponOrder.builder()
                .grouponOrderId(grouponOrderId)
                .payId(payAmountId)
                .storeNo(request.getStoreNo())
                .gcId(request.getGrouponCouponsId())
                .userId(request.getUserId())
                .deductionCouponId(deductionCoupon.getId())
                .paymentMethod(PayMethod.WECHAT_PAY)
                .ticketNumber(request.getNumber())
                .totalAmount(totalAmount)
                .status(OrderStatus.TO_BE_PAID.getCode())
                .build();
        //更新数据库中的数据
        grouponCouponsMapper.updateById(grouponCoupons);
        //先数据库增加订单记录
        grouponOrderMapper.insert(grouponOrder);

        //检查该下单用户是否满足返利给邀请人优惠券的条件
        checkRebateCondition(grouponOrder.getUserId(), grouponOrderId);
    }

    /**
     * 调用第三方支付接口,生成订单记录并记录流水
     *
     * @param buyGrouponCouponsRequest 下单团购优惠券参数类
     * @return BaseResponse<Boolean>
     * @author Manner
     * @date 2024/10/12 22:09
     */
    @Transactional(rollbackFor = Throwable.class)
    public BaseResponse<String> setOutOrderPreData(GrouponCoupons grouponCoupons,
                                                   BuyGrouponCouponsRequest buyGrouponCouponsRequest) {
        String thirdPartyPayAmountId = String.valueOf(redisIdWorker.nextId("groupon_order"));
        //生成年月日时分秒+随机七位整数的团购订单编号
        String grouponOrderId = grouponOrderIdGenerate.generateOrderNumber().toString();
        //获取优惠券总支付金额
        BigDecimal totalAmount = buyGrouponCouponsRequest.getTotalAmount();
        //扣减优惠券库存,生成订单记录
        generateGrouponOrder(
                grouponOrderId,
                thirdPartyPayAmountId,
                totalAmount,
                buyGrouponCouponsRequest,
                grouponCoupons
        );
        //转换金额
        int total = buyGrouponCouponsRequest.
                getTotalAmount()
                .multiply(new BigDecimal(100))
                .setScale(0, BigDecimal.ROUND_HALF_UP)
                .intValue();
        //调用支付接口
        String payResult = payService.pay(new PayDTO(
                grouponOrderId,
                buyGrouponCouponsRequest.getCode(),
                total,
                buyGrouponCouponsRequest.getDescription()
        ));
        //返回数据
        return ResultUtils.success("操作成功").add(payResult);
    }

    /**
     * 检查以往购买的数量和现在购买的数量总和,有没有超过限制购买的数量
     *
     * @param grouponCoupons           团购优惠券信息
     * @param buyGrouponCouponsRequest 下单团购优惠券参数
     * @return String
     * @author Manner
     * @date 2024/10/12 16:08
     */
    public BaseResponse<String> checkUserGrouponCouponsWhetherAvailableNumber(GrouponCoupons grouponCoupons, BuyGrouponCouponsRequest buyGrouponCouponsRequest) {
        LocalDate now = LocalDate.now();
        LocalDateTime start = LocalDateTime.of(now, LocalTime.MIN);
        LocalDateTime end = LocalDateTime.of(now, LocalTime.MAX);
        //限购,且购买数量小于等于限制数量,检查团购券订单表核验该用户以前购买的这张优惠券数量
        List<GrouponOrder> userOldGCOrders = grouponOrderMapper.selectList(new LambdaQueryWrapper<GrouponOrder>()
                //用户编号
                .eq(GrouponOrder::getUserId, buyGrouponCouponsRequest.getUserId())
                //商家编号
                .eq(GrouponOrder::getStoreNo, buyGrouponCouponsRequest.getStoreNo())
                //团购优惠券编号
                .eq(GrouponOrder::getGcId, buyGrouponCouponsRequest.getGrouponCouponsId())
                //时间
                .between(GrouponOrder::getCreateTime, start, end)
        );
        if (userOldGCOrders.size() > 0) {
            Integer purchasedNumber = 0;
            //统计该用户已经购买的这张优惠券数量
            for (GrouponOrder order : userOldGCOrders) {
                Integer status = order.getStatus();
                //订单状态为 已取消 已退款 不算用户个人限购数
                if (status != OrderStatus.CANCELED.getCode() && status != OrderStatus.REFUNDED.getCode() && status != OrderStatus.TO_BE_PAID.getCode()) {
                    purchasedNumber = purchasedNumber + order.getTicketNumber();
                }
            }
            //限购数量用完
            if (purchasedNumber == grouponCoupons.getCanBuy()) {
                return ResultUtils.error(500, "团购优惠券限购数量已用完!");
            }
            //限购数量不够
            if ((purchasedNumber + buyGrouponCouponsRequest.getNumber()) > grouponCoupons.getCanBuy()) {
                return ResultUtils.error(500, "团购优惠券限购数量不足!");
            }
        }
        return setOutOrderPreData(grouponCoupons, buyGrouponCouponsRequest);
    }

    /**
     * 用户下单优惠券
     *
     * @param buyGrouponCouponsRequest
     * @return BaseResponse<Boolean>
     * @author Manner
     * @date 2024/10/12 16:24
     */
    @Transactional(rollbackFor = Throwable.class)
    @Override
    public BaseResponse<String> addGroupCouponsGenerateOrder(BuyGrouponCouponsRequest buyGrouponCouponsRequest) {
        //根据编号查询目标团购券信息
        GrouponCoupons grouponCoupons = grouponCouponsMapper.selectById(buyGrouponCouponsRequest.getGrouponCouponsId());
        //判断库存是否充足
        if (grouponCoupons.getStock() < buyGrouponCouponsRequest.getNumber()) {
            //库存不足
            throw new CustomException("优惠券库存不足!");
        }
        //库存充足,判断团购券是限购还是不限购
        if (grouponCoupons.getCanBuy() != -1) {
            if (buyGrouponCouponsRequest.getNumber() > grouponCoupons.getCanBuy()) {
                //单次购买数直接超过限购数量
                throw new CustomException("超过限制购买数!");
            }
        }
        //限购,并且判断购买数和限购数比较
        //检查以往购买的数量和现在购买数量的总和,有没有超过限制购买的数量,直接生成订单记录流水
        return checkUserGrouponCouponsWhetherAvailableNumber(grouponCoupons, buyGrouponCouponsRequest);
    }

    /**
     * 根据编号查询优惠券以及关联商品套餐信息
     *
     * @param id 优惠券编号
     * @return BaseResponse<GroupCouponVo>
     * @author Manner
     * @date 2024/10/13 15:17
     */
    @Override
    public BaseResponse<GroupCouponVo> queryById(Long id) {
        //获取团购券数据
        GrouponCoupons coupons = getById(id);
        //获取团购券套餐数据
        List<GroupPurchasePackage> list = groupPurchasePackageService.query().eq("gcid", id).list();
        //准备容器
        List<GroupCouponPackageVo> container = new ArrayList<>();
        //反射对象
        ArrayList<CouponItem> classObject = new ArrayList<>();
        //遍历
        list.forEach(item -> {
            List<CouponItem> items = new ArrayList<>();
            try {
                JSONArray jsonArray = JSONUtil.parseArray(item.getGpContent());
                //转为集合
                items = JSONUtil.toList(jsonArray, CouponItem.class);
            } catch (Exception e) {
                log.error("转换失败");
            } finally {
                container.add(new GroupCouponPackageVo(item.getGpTitle(), items));
            }
        });
        //返回数据
        return ResultUtils.success(new GroupCouponVo(coupons, container));
    }


    @Override
    public BaseResponse<PageResult<AdminCouponVO>> search(PageRequest page, String storeId, String name, int status) {
        //构建分页参数
        Page<GrouponCoupons> iPage = new Page<>(page.getCurrent(), page.getPageSize());
        //构建查询参数
        QueryWrapper<GrouponCoupons> wrapper = new QueryWrapper<>();
        //判断
        if (storeId != null && storeId != "") {
            wrapper.eq("store_id", storeId);
        }
        if (name != null && name != "") {
            wrapper.like("title", '%' + name + '%');
        }
        if (status != 2) {
            wrapper.eq("status", status);
        }
        wrapper.orderByDesc("create_time");
        //查询数据
        Page<GrouponCoupons> result = grouponCouponsMapper.selectPage(iPage, wrapper);
        //准备容器
        List<AdminCouponVO> list = new ArrayList<>();
        //获取商家信息
        result.getRecords().forEach(item -> {
            //获取商家数据
            Store store = storeMapper.selectOne(new QueryWrapper<Store>().eq("store_no", item.getStoreId()));
            //添加容器
            list.add(new AdminCouponVO(item.getId(), item.getStoreId(), item.getTitle(), item.getImg(), item.getPrice(), item.getEffectDay(), item.getCanBuy(),
                    item.getIsToGo(), item.getDiscount(), item.getProfit(), item.getSoldCount(), item.getUnLinePrice(), item.getStock(), item.getStatus(), item.getIsDelete(),
                    item.getCreateTime(), item.getUpdateTime(), store.getName(), item.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"))));
        });
        //返回数据
        return ResultUtils.success(new PageResult<>(list, result.getTotal()));
    }

    @Override
    public BaseResponse<String> cancel(Long id) {
        //判断该用户是否有未支付的订单
        Long count = grouponOrderMapper.selectCount(new QueryWrapper<GrouponOrder>().eq("user_id", id).eq("status", OrderStatus.TO_BE_PAID.getCode()));
        //判断
        if (count < 0) {
            throw new CustomException("没有待支付的订单!");
        }
        //取消
        grouponOrderMapper.delete(new QueryWrapper<GrouponOrder>().eq("user_id", id).eq("status", OrderStatus.TO_BE_PAID.getCode()));
        //返回数据
        return ResultUtils.success("订单取消支付");
    }

    /**
     * @param args 所需参数封装类
     * @return Double
     * @description: 计算用户和店铺的距离(单位 : 米)
     * @author Manner
     * @date 2024/12/8 16:33
     */
    public Double calculateDistance(CalculationDistanceArgs args) {
        //拼接生成示例---> user:15:distance:store:SJ64165165165165
        String distanceKey = "user:" + args.getUserId() + ":distance:store:" + args.getStoreNo() + "";
        try {
            //将用户和店铺的经纬度信息存入到Redis当中
            stringRedisTemplate.opsForGeo().add(distanceKey, new Point(args.getUserLongitude(), args.getUserLatitude()), "user");
            stringRedisTemplate.opsForGeo().add(distanceKey, new Point(args.getStoreLongitude(), args.getStoreLatitude()), "store");

            //计算距离
            Distance distance = stringRedisTemplate.opsForGeo().distance(distanceKey, "user", "store", RedisGeoCommands.DistanceUnit.METERS);
            //删除临时计算的数据
            stringRedisTemplate.delete(distanceKey);
            return BeanUtil.isNotEmpty(distance) ? distance.getValue() : Double.valueOf(USER_DIRECT_REFUND_DISTANCE + 1);
        } catch (Exception e) {
            stringRedisTemplate.delete(distanceKey);
            throw new CustomException("计算距离时出现错误!");
        }
    }

    /**
     * @param no            订单编号
     * @param userLongitude 用户所在位置经度
     * @param userLatitude  用户所在位置纬度
     * @return BaseResponse<String>
     * @description: 用户退款团购订单
     * @author Manner
     * @date 2024/12/8 16:19
     */
    @Override
    public BaseResponse<String> refund(String no, Double userLongitude, Double userLatitude) {
        //查询订单数据
        GrouponOrder order = grouponOrderMapper.selectOne(new LambdaQueryWrapper<GrouponOrder>()
                .eq(GrouponOrder::getGrouponOrderId, no));
        //店铺信息
        Store store = storeMapper.selectOne(new LambdaQueryWrapper<Store>().eq(Store::getStoreNo, order.getStoreNo()));
        //检测店铺是否存在以及信息完整
        if (BeanUtil.isEmpty(store) || BeanUtil.isEmpty(store.getLongitude()) || BeanUtil.isEmpty(store.getLatitude())) {
            throw new CustomException("店铺位置信息错误!");
        }
        //构建计算用户和店铺之间距离的所需的参数对象
        CalculationDistanceArgs distanceArgs = CalculationDistanceArgs.builder()
                .userId(order.getUserId())
                .storeNo(order.getStoreNo())
                .userLongitude(userLongitude)
                .userLatitude(userLatitude)
                .storeLongitude(store.getLongitude())
                .storeLatitude(store.getLatitude())
                .build();
        //计算出用户与门店距离米数
        Double distanceMilesNumber = calculateDistance(distanceArgs);

        System.out.println("距离:" + distanceMilesNumber);

        //直接退款
        if (distanceMilesNumber > USER_DIRECT_REFUND_DISTANCE) {
            //退款
            boolean refund = payService.refund(order);
            //判断
            if (refund) {
                //修改状态
                order.setStatus(REFUND_LOADING.getCode());
                grouponOrderMapper.updateById(order);
                return ResultUtils.success("退款中,请稍侯");
            } else {
                return ResultUtils.fail("退款失败");
            }
        } else { //需要审批
            //构建审批对象信息
            RefundApprovalRecord refundApprovalRecord = RefundApprovalRecord.builder()
                    .userId(order.getUserId())
                    .storeNo(order.getStoreNo())
                    .grouponOrderNo(order.getGrouponOrderId())
                    .grouponCouponId(order.getGcId())
                    .money(order.getTotalAmount())
                    .status(UNDER_APPROVAL.getCode())
                    .build();
            //设置订单状态为退款中
            order.setStatus(REFUND_LOADING.getCode());
            //更新数据库
            grouponOrderMapper.updateById(order);
            //生成一条新的审批记录到数据库中
            refundApprovalRecordMapper.insert(refundApprovalRecord);
            throw new CustomException("退款正在审批中,请与商家协商!");
        }
    }
}